package com.example.myspringframework.context.event;

import com.example.myspringframework.beans.BeansException;
import com.example.myspringframework.context.ApplicationEvent;
import com.example.myspringframework.context.ApplicationListener;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
    /**
     * 事件发布的功能
     *
     * @param event
     */
    @Override
    public void multicastEvent(ApplicationEvent event) {
        for (ApplicationListener<ApplicationEvent> applicationListener : this.applicationListeners) {
            if (this.supportsEvent(applicationListener, event)) {
                applicationListener.onApplicationEvent(event);
            }
        }
    }

    /**
     * 判断监听器是否监听该事件
     */
    protected boolean supportsEvent(ApplicationListener<ApplicationEvent> applicationListener, ApplicationEvent event) {
        // 获取这个类所实现的所有泛型接口
        Type type = applicationListener.getClass().getGenericInterfaces()[0];
        // 获取泛型中实际的类型参数
        Type actualTypeArgument = ((ParameterizedType) type).getActualTypeArguments()[0];
        // 获取泛型参数的全限定类名
        String className = actualTypeArgument.getTypeName();
        Class<?> eventClassName;
        try {
            eventClassName = Class.forName(className);
        } catch (ClassNotFoundException e) {
            throw new BeansException("wrong event class name: " + className);
        }
        return eventClassName.isAssignableFrom(event.getClass());
    }
}
